import math
import sys
from typing import List, Dict


class SpeedInterval:

    @staticmethod
    def analysis(highest_level: int, lowest_level: int, ship_info_list: List[tuple]) -> List[Dict]:
        """

        :param highest_level: 最高的区间的起始速度
        :param lowest_level: 最低的区间的起始速度
        :param ship_info_list: (时间, 经度, 维度, 速度) 四元组列表, 格式是datetime, float, float, float
        :return: 元素为每个区间信息的列表,包含startSpeed:区间的最低速度, endSpeed:区间的最高速度, totalSecond:总秒数, rate:占总时间的比例
        """
        lowest_level = math.floor(lowest_level)
        # 每个速度区间的起始速度
        start_speeds = [x for x in range(lowest_level, highest_level + 1)]
        num = len(start_speeds)
        # 每个速度区间的时间(单位秒)
        intervals = [0 for _ in range(num)]
        # if not ship_info_list or len(ship_info_list) == 1:
        #     return []
        start_time = ship_info_list[0][0]
        start_speed = ship_info_list[0][3]
        for info in ship_info_list[1:]:
            end_time = info[0]
            end_speed = info[3]
            start_speed, end_speed = max(start_speed, end_speed), min(start_speed, end_speed)
            interval_seconds = (end_time - start_time).total_seconds()
            interval_speed = start_speed - end_speed
            if interval_speed == 0:
                if start_speed >= lowest_level:
                    intervals[min(math.floor(start_speed) - lowest_level, num - 1)] += interval_seconds
            else:
                for i in range(num):
                    down = start_speeds[i]
                    up = down + 1 if i < num - 1 else sys.maxsize
                    rate = max(min(start_speed, up) - max(end_speed, down), 0) / interval_speed
                    intervals[int(down - lowest_level)] += interval_seconds * rate
            start_time = end_time
            start_speed = end_speed

        result = []
        # 总时间
        # total_seconds = (ship_info_list[-1][0] - ship_info_list[0][0]).total_seconds()
        # 区间内的总时间
        total_seconds = sum(intervals)
        for i in range(num):
            temp = {}
            down = start_speeds[i]
            up = down + 1 if i < num - 1 else sys.maxsize
            temp.update(startSpeed=down, endSpeed=up, totalSecond=int(intervals[i]), rate=intervals[i] / total_seconds if total_seconds else 0)
            result.append(temp)
        return result

